/**boxes表示每个位含有小球数 返回将所有小球移动到第 i 个盒子所需的 最小 操作数
 * @param {string} boxes
 * @return {number[]}
 * 前缀和解法 时间复杂度O(n)
 */
var minOperations = function (boxes) {
    // cntL计算每个位（含当前）左边有几个1
    const cntL = Array(boxes.length).fill(0)
    // left计算每个位左边的1移动到当前位需要的操作数
    const left = Array(boxes.length).fill(0)
    cntL[0] = boxes[0] == '1' ? 1 : 0
    for (let i = 1; i < boxes.length; i++) {
        if (boxes[i] == '1') {
            cntL[i] = cntL[i - 1] + 1
        } else {
            cntL[i] = cntL[i - 1]
        }
    }
    for (let i = 1; i < boxes.length; i++) {
        // 当前位操作次数 = 上一位操作次数 + 之前的1的个数
        left[i] = left[i - 1] + cntL[i - 1]
    }

    // 右侧同理
    const cntR = Array(boxes.length).fill(0)
    const right = Array(boxes.length).fill(0)
    cntR[boxes.length - 1] = boxes[boxes.length - 1] == '1' ? 1 : 0
    for (let i = boxes.length - 2; i >= 0; i--) {
        if (boxes[i] == '1') {
            cntR[i] = cntR[i + 1] + 1
        } else {
            cntR[i] = cntR[i + 1]
        }
    }
    for (let i = boxes.length - 2; i >= 0; i--) {
        right[i] = right[i + 1] + cntR[i + 1]
    }

    // 左边操作数+右边操作数=总操作数
    const result = Array(boxes.length)
    for (let i = 0; i < result.length; i++) {
        result[i] = left[i] + right[i]
    }

    return result
};